<template>
  <div class="setup">
    <div class="setup-header">
      <div>组合式Store</div>

      <div>
        <button @click="setupStore.increment()">递增</button>

        <!-- 组合式API中无$reset，可在Store中自定义该$reset -->

        <!-- $patch用于同时变更多个State -->
        <button @click="patch">变更</button>

        <!-- $subscribe用于监听State的变化 -->
        <button @click="subscribe">订阅State</button>
        <button @click="unsubscribe">不订阅State</button>

        <!-- $onAction用于监听Action和结果的变化 -->
        <button @click="asynchronous">调用action</button>
        <button @click="onAction">订阅Action</button>
        <button @click="unOnAction()">不订阅Action</button>
      </div>
    </div>

    <div class="setup-body">
      <div class="setup-body__item" v-for="item in lists">
        <div class="setup-body__label">{{ item.label }}</div>
        <div class="setup-body__value">{{ item.value }}</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {useSetupStore} from '@/stores/setup.js';
import {computed} from 'vue';

const setupStore = useSetupStore();

// 解构无法响应式更新
const {string, number, boolean, array, object, encrypt, asynchronous} = setupStore;
console.log('解构', string); // SYX
console.log('解构', number); // 10
console.log('解构', boolean); // true
console.log('解构', array); // Proxy(Array) {0: 'A', 1: 'B', 2: 'C'}
console.log('解构', object); // Proxy(Object) {name: 'SYX', age: 19}
console.log('解构', encrypt); // 加密**SYX**加密
asynchronous(); // 异步Promise

// computed保证响应式更新
const computedCount = computed(() => setupStore.number);

const patch = () => {
  // $patch用于同时变更多个State，允许将多个变更归入Devtools的同一条目中
  setupStore.$patch({
    string: 'TNT',
    number: 20,
  });

  setupStore.$patch((state) => {
    state.boolean = false;
    state.array.push('D');
  });

  console.log('$patch', setupStore.string); // TNT
  console.log('$patch', setupStore.number); // 20
  console.log('$patch', setupStore.boolean); // false
  console.log('$patch', setupStore.array); // Proxy(Array) {0: 'A', 1: 'B', 2: 'C', 3: 'D'}
};

let unsubscribe = null;
const subscribe = () => {
  // $subscribe用于监听State的变化，与watch不同的是$subscribe只在$patch后触发一次。组件被卸载时订阅被删除，若不想删除可将参数二设置为{detached: true}
  unsubscribe = setupStore.$subscribe((mutation, state) => {
    console.log('监听到变化');
  });
};

let unOnAction = null;
const onAction = () => {
  // $onAction用于监听Action和结果的变化。组件被卸载时订阅被删除，若不想删除可将参数二设置为true
  unOnAction = setupStore.$onAction(({name, store, args, after, onError}) => {
    // name表示action名称、store表示Store实例、args表示传递给action的参数数组
    console.log('action前触发', name); // asynchronous

    // after表示action成功并完全运行后触发
    after((result) => {
      console.log('action成功并完全运行后触发', result); // undefined
    });

    // onError表示action异常或返回拒绝Promise触发
    onError((error) => {
      console.log('action异常或返回拒绝Promise触发', error);
    });
  });
};

const lists = computed(() => {
  return [
    {
      label: '对象',
      value: setupStore.number
    },
    {
      label: '解构',
      value: number
    },
    {
      label: '计算属性',
      value: computedCount
    },
  ];
});
</script>

<style scoped>
.setup-header {
  font-weight: bold;
  display: flex;
  align-items: center;
  column-gap: 20px;
  margin-bottom: 10px;

  & button {
    margin-right: 10px;
  }
}

.setup-body__item {
  display: flex;
  align-items: center;
  column-gap: 20px;
  margin-top: 5px;
}

.setup-body__label {
  width: 60px;
  font-size: 14px
}

.setup-body__value {
  padding: 2px 10px;
  border: 1px solid gainsboro;
  font-size: 12px;
  font-weight: bold;
  color: grey;
}
</style>